{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 基本类型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中不需要声明变量的类型  \n",
    "常见的基本类型有int, float, bool, NoneType, str"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = 1\n",
    "b = 0.5\n",
    "c = True\n",
    "d = None\n",
    "e = \"String\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以使用print()函数打印变量，默认在打印内容结尾处换行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)\n",
    "print(b)\n",
    "print(c)\n",
    "print(d)\n",
    "print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "print中支持多个参数，可用逗号隔开  \n",
    "打印结果被空格隔开"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a, b)\n",
    "print(c, d, e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个变量名可以被反复赋值，而且不限类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1\n",
    "print(a)\n",
    "\n",
    "a = 2\n",
    "print(a)\n",
    "\n",
    "a = None\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用type()函数查看变量类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(type(a))\n",
    "print(type(b))\n",
    "print(type(c))\n",
    "print(type(d))\n",
    "print(type(e))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在python3中，int类型和float类型是没有限制大小的，即它的长度只受限于机器的内存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "int和float类型支持加减乘除、乘方、求余等操作  \n",
    "与c、java不同的是，python3中对于整数的的除法，结果为float类型，如果要和C一样得到整数值需要用\"//\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3\n",
    "b = 2\n",
    "c = 1.5\n",
    "print(a + b) # 3 + 2\n",
    "print(a + c) # 3 + 1.5\n",
    "print(a * c) # 3 * 1.5\n",
    "print(a / b) # 3 / 2\n",
    "print(a / c) # 3 / 1.5\n",
    "print(a // b) # 3 // 2\n",
    "print(a**2)  # a^2\n",
    "print(a**3)  # a^3\n",
    "print(a % b) # a % b\n",
    "print(b % c) # b % c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与、或、非 在python中分别为and, or, not"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(1 < 2 and 2 < 3)\n",
    "print(1 < 2 and 2 > 3)\n",
    "print(1 < 2 or 2 > 3)\n",
    "print(1 > 2 or 2 > 3)\n",
    "print(not 1 > 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. list（列表）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "list是python中最简单，最基础的容器类型，它的特征是一对中括号[ ]  \n",
    "list中的元素可以是同类型的，也可以是不同类型的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# list的初始化\n",
    "a = []\n",
    "print(a)\n",
    "\n",
    "a = list()\n",
    "print(a)\n",
    "\n",
    "a = [1, 2, 3]\n",
    "print(a)\n",
    "\n",
    "a = [1, 2, None, True, \"String\"]\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在不考虑内存大小的情况下，list内的空间是无限大的，我们使用len()函数，获取一个列表的长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(len(a)) #列表a的长度\n",
    "\n",
    "print(len([])) # 空列表的长度\n",
    "\n",
    "print(len(list())) # 空列表的长度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在python中，访问列表中的元素使用它的index  \n",
    "使用list[index]访问第index+1个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)\n",
    "print(a[0])\n",
    "print(a[1])\n",
    "print(a[2])\n",
    "print(a[3])\n",
    "print(a[4])\n",
    "print(a[5]) # 越界\n",
    "print(1 in a) # 1是否在列表a中\n",
    "print(\"haha\" in a) # \"haha\"是否在列表a中"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在python中，可以对列表进行切片(slice)，截取多个元素  \n",
    "list[start: end: step_size]  \n",
    "需要注意的是，start指向的元素会被选中，从start到end-1都会被选中，end指向的元素不会被选中  \n",
    "step_size不指定时，默认为1，即从start到end-1每个元素都被选中，放入新列表中返回"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)\n",
    "print(a[:])    # 不指定start和end时，默认为0和len(a)，即取列表中的所有元素，并返回一个新列表\n",
    "print(a[0:])   # 从第1个元素到最后一个元素\n",
    "print(a[2:])   # 从第3个元素到最后一个元素\n",
    "print(a[1:5])  # 从第2个元素到第5个元素(index为4)\n",
    "print(a[:-1])  # 从第1个元素到倒数第2个元素\n",
    "print(a[:-3])  # 从第1个元素到倒数第4个元素\n",
    "print(a[::1])  # 从第1个元素到最后一个元素，每个元素都取\n",
    "print(a[::2])  # 从第1个元素到最后一个元素，每隔1个元素取一次\n",
    "print(a[1::2]) # 从第2个元素到最有一个元素，每隔1个元素取一次"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python列表一个很强大的功能是列表生成式，格式为[*expr* for *element* in *list*]， *expr*为表达式(可以是对*element*的操作也可以和*element*无关)，*element*为循环中的每一个元素，*list*为列表(实际上任何可迭代对象都可以)\n",
    "比如说要生成从0到9每个数字的平方，可以用\n",
    "```python\n",
    "result = [i**2 for i in range(10)]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print([i**2 for i in range(10)]) # 1到9每个数字的平方\n",
    "print([type(x) for x in a]) # a中每个元素的类型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### test1: 同样的道理，在取元素的时候，index也可以为负数  \n",
    "尝试取列表a中的倒数第3个元素，将其存入b中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, None, True, \"String\"]\n",
    "# 尝试取列表a中的倒数第3个元素，将其存入b中\n",
    "# ------start code------\n",
    "b = a[-3]\n",
    "\n",
    "# ------end code------\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表是一种类型，是python内置的类型，该类型有很多常用的方法(method)  \n",
    "比如：添加元素，删除元素，对列表进行排序，查找一个值第一次出现的位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在列表的末尾插入一个元素\n",
    "print('before append an element:')\n",
    "print(a)\n",
    "a.append(\"new element\")\n",
    "print('after append an element:')\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在列表的任意位置插入一个元素\n",
    "print('before insert an element:')\n",
    "print(a)\n",
    "a.insert(1, \"new element2\") # 在下标(index)为1的地方插入一个字符串\"new element2\"\n",
    "print('after insert an element:')\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 删除第二个元素，并返回\n",
    "print(\"before delete the second element:\")\n",
    "print(a)\n",
    "b = a.pop(1) # 删除第二个元素，index为1，并返回，赋值给b\n",
    "print(\"after delete the second element:\")\n",
    "print(a)\n",
    "print(\"the second element in list a before delete:\", b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 删除第一次出现的一个元素\n",
    "a = [1, 2, 3, 1, 2]\n",
    "print(a)\n",
    "a.remove(1) # 删除从左到右第一个出现的1\n",
    "print(a)\n",
    "a.remove(1) # 删除从左到右第一个出现的1\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对列表进行原地排序\n",
    "a = [5, 3, 1, 4, 7, 3, 9, 0]\n",
    "a.sort() # 对a进行从小打大排序\n",
    "print(a)\n",
    "a.sort(reverse = True) # 对a进行从大到小排序\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查找第一次出现的一个值\n",
    "a = [1, 2, 3, 4, 1, 2, 3, 4]\n",
    "print(a.index(2)) # 打印出从左到右，2这个元素第一次出现的index值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还可以使用help()函数查看文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(list) # 使用help函数，查看list的文档"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "方法名前后有两个下划线的，称为魔术方法（magic methods），属于python的高级技巧  \n",
    "\n",
    "list里的其他方法：  \n",
    "1. clear：清空列表  \n",
    "a.clear() 即清空a  \n",
    "\n",
    "2. copy：复制当前列表并返回  \n",
    "a.copy() 赋值列表a并返回  \n",
    "\n",
    "3. count：返回一个指定的元素在列表中的出现次数  \n",
    "a.count(b) 返回列表a中b的出现次数  \n",
    "\n",
    "4. extend：将另一个可迭代的元素里面的所有元素添加到当前的列表中  \n",
    "a.extend(b)  b是一个列表，将b中的元素扩展到a中  \n",
    "\n",
    "5. reverse: 原地转置  \n",
    "a.reverse() 将a中的元素前后转置  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### test2: 在下方尝试上面的这5个方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5]\n",
    "# 在下方使用clear方法\n",
    "# ------start code------\n",
    "a.clear()\n",
    "\n",
    "# ------end code------\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5]\n",
    "# 在下方使用copy方法，复制给b\n",
    "# ------start code------\n",
    "b = a.copy()\n",
    "\n",
    "# ------end code------\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5, 1, 3, 6, 2, 4, 1, 4, 2, 6, 8, 2]\n",
    "# 在下方使用count方法，数出列表a内2的个数\n",
    "# ------start code------\n",
    "number = a.count(2)\n",
    "\n",
    "# ------end code------\n",
    "print(number)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5]\n",
    "b = [6, 2, 4, 1, 6, 0]\n",
    "# 在下方使用extend方法，将b中的元素扩展到a中\n",
    "# ------start code------\n",
    "a.extend(b)\n",
    "\n",
    "# ------end code------\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5, 1, 3, 6, 2, 4, 1, 4, 2, 6, 8, 2]\n",
    "# 在下方使用reverse方法，将a中的元素转置\n",
    "# ------start code------\n",
    "a.reverse()\n",
    "\n",
    "# ------end code------\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### test3: 与刚才的len()函数类似，python还内置了很多类似的函数，比如max(), min()  \n",
    "max()用来求一个可迭代对象中的最大值，如max(a)  \n",
    "min()用来求一个可迭代对象中的最小值，如min(a)  \n",
    "在下方使用max函数，将a中的最大值存到max_value中，使用min函数，将最小值存到min_value中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4, 5, 1, 3, 6, 2, 4, 1, 4, 2, 6, 8, 2]\n",
    "# 在下方使用max函数，将a中的最大值存到max_value中，使用min函数，将最小值存到min_value中\n",
    "# ------start code------\n",
    "max_value = a.max()\n",
    "min_value = a.min()\n",
    "# ------end code------\n",
    "print(max_value)\n",
    "print(min_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 元组(tuple)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组是一种不可变的类型，它和list类似，但是list是可变的，tuple不可变，它的标志是\"()\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化一个tuple\n",
    "a = ()\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tuple()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化一个有元素的tuple\n",
    "a = (1, 2, 3)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化一个仅有一个元素的tuple\n",
    "a = (1, )\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化一个元素的tuple时，如果不加逗号，python会将小括号理解成数值运算里的括号\n",
    "a = (1)\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "和list类似，我们需要用a[index]来访问元组a中的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, 2, 3)\n",
    "print(a[0])\n",
    "print(a[1])\n",
    "print(a[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样，tuple也是可以用切片取多个元素的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, 2, 3, 4, 5, 6, 7, 8, 9)\n",
    "print(a[::2]) # 取index为偶数的元素\n",
    "print(a[1::2])# 取index为奇数的元素\n",
    "print(a[:])   # 取所有的元素\n",
    "print(a[:-5]) # 取第一个元素到倒数第六个元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于不可变，元组自然也就没有list那样的sort和reverse方法了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(tuple)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## test1\n",
    "列表这个类型有个sort方法，可以就地排序，但是调用这个方法后，并没有返回值，python提供了一个叫做sorted的函数，可以将一个可迭代对象内的元素排序后放到一个新list中返回"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [5, 2, 3, 1, 9, 4, 8]\n",
    "b = sorted(a)\n",
    "print(b)\n",
    "c = sorted(a, reverse = True)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请尝试对下面的元组a调用sorted函数，将a按从小到大排序的结果存入b中，将a按从大到小排序的结果存入c中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# test1\n",
    "a = (5, 2, 3, 1, 9, 4, 8)\n",
    "# ------ start code ------\n",
    "b = sorted(a)\n",
    "c = sorted(a, reverse=True)\n",
    "# ------ end code ------\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上次我们提到了max函数，min函数，分别用于求一个可迭代对象中的最大值与最小值，len函数用于求一个容器对象的长度，python中还内置了一个sum函数，用于求一个容器内元素的和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1.1, 2.2, 3.3, 4.4)\n",
    "b = sum(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是如果要使用sum函数对某一个可迭代对象求和，这个可迭代对象里必须都是数值型的类型，比如int和float，如果出现了其他类型，则会报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, \"list\", 2, \"tuple\")\n",
    "print(sum(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请使用**切片(slice)**将元组a中index为偶数的元素取出，并将他们的和存入summation中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = (1, \"list\", 2, \"tuple\", 3, \"dict\", 4, \"set\")\n",
    "# ------ start code ------\n",
    "\n",
    "summation = a[::2]\n",
    "\n",
    "# ------ end code ------\n",
    "print(summation)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中并没有求一个容器平均值的函数，不过python提供了**求和**与**求长度（元素个数）**的函数，请使用这两个函数求下面元组a中元素的平均值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = (1, 2, 3, 4, 5, 6)\n",
    "# ------ start code ------\n",
    "\n",
    "average = a.sum()/len(a)\n",
    "\n",
    "# ------ end code ------\n",
    "print(average)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python与其他语言一样，提供了强制类型转换的**函数**，常见的有int, float, str, list, tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将a转换为浮点型\n",
    "a = \"3.14\"\n",
    "b = float(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将a转换为整型\n",
    "a = \"3\"\n",
    "b = int(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将a转换为整型\n",
    "a = \"1\"\n",
    "b = int(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将a转换为整型\n",
    "a = 3.99\n",
    "b = int(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，int这个函数，可以将float（小数）转换为整数，但是它会向着趋近于0的方向取整，所以即便是3.99，也会被转换为3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请将下面的字符串a，转换为整型(int)，存入b中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"-3.14\"\n",
    "# ------ start code ------\n",
    "\n",
    "b = int(float(a))\n",
    "\n",
    "# ------ end code ------\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样的，list与tuple也可作为强制类型转换的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, 2, 3)\n",
    "b = list(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3]\n",
    "b = tuple(a)\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 关于tuple的不可变"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "什么是可变，什么是不可变，tuple的不可变体现在哪里？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3, 4]\n",
    "a[0] = 5\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, 2, 3, 4)\n",
    "a[0] = 5\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一旦元组被生成，里面的元素就不可变了，不允许添加、删除以及修改里面的元素, **但是**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3]\n",
    "b = (a, 1, 2)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.append(4)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 打印b试试\n",
    "# ------ start code ------\n",
    "print(b)\n",
    "# ------ end code ------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请思考为什么会发生这样的现象？  \n",
    "原因可见这篇文章里面的第五条http://www.jianshu.com/p/9963435e2641"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的字符串很强大，内置了多种方法，字符串的特征是\" \", ' ', ''' ''', \"\"\" \"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 'Tom'\n",
    "b = \"Tom\"\n",
    "print(a == b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "单引号和双引号没有什么区别"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "三个引号用于多行的字符串，普通的单引号和双引号是不能实现这个功能的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = '''Tom\n",
    "and\n",
    "Jack\n",
    "'''\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 'Tom\n",
    "and\n",
    "Jack'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里说一下python字符串一些常用操作：\n",
    "- 字符串拼接：`str1+str2`\n",
    "- 去空格：`str.strip()`\n",
    "- 格式化： `\"%d%f%s\"%(int1, float1, string1)`\n",
    "- 大小写：`str.upper(), str.lower()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('foo '+' bar')\n",
    "print('  ver  bo  se '.strip())\n",
    "print('int: %d, float: %f, string: %s'%(1, 3.14, 'my god'))\n",
    "print('Big Small'.upper(), 'Big Small'.lower())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用len()函数可以查看字符串的长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(\"Tom\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test1\n",
    "尝试对字符串a使用max和min函数，并打印结果，分析原因"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# test1\n",
    "a = \"Tom\"\n",
    "# ------ start code ------\n",
    "print(min(a))\n",
    "print(max(a))\n",
    "\n",
    "# ------ end code ------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当你有两个字符串，并且想将他们合成为一个字符串的时候，可以使用加号(+)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"Tom\"\n",
    "b = \"Jarry\"\n",
    "print(a+b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串有两个常用方法，一个是startswith, 另一个是endswith，前者用于判断一个字符串是否以某一个字符串为开头，后者用于判断是否以某一字符串为结尾"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(help(str.startswith))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(help(str.endswith))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"Tom and Jarry\"\n",
    "print(a.startswith('Tom'))\n",
    "print(a.endswith(\"Jarry\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第二个比较常用的方法是split，用于分割字符串，返回一个list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(help(str.split))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"Tom and Jarry\"\n",
    "print(a.split(' '))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第三个比较常用的方法是replace，用于替换字符串中的子字符串，将替换后的字符串返回，该操作不会影响原字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(help(str.replace))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"Tom and Jarry\"\n",
    "b = a.replace('Tom', 'Jack')\n",
    "print(b)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第四个常用的方法是strip，这个方法常用于读文件，或是清理爬虫抓取的内容，很多时候我们读的文件，结尾可能有很多没有用的换行符或空格，如果不处理的话容易引发bug，strip可以清除字符串首尾两侧的空格或换行符等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \" Tom and Jarry    \\n\"\n",
    "b = a.strip()\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在此需要提一句，在这种交互式环境下，即使不用print也可以打印一个变量的值，直接输入变量名即可，但是这种方法与print函数打印出的内容不同，print函数会自动解析换行符等字符，但是直接使用变量名显示变量值的方法却不能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \" Tom and Jarry    \\n\"\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \" Tom and Jarry    \\n\"\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还有一些比较常用的方法，比如lower和upper，可以将字符串中所有的字符换成小写或大写"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \" Tom and Jarry    \\n\"\n",
    "a.lower()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \" Tom and Jarry    \\n\"\n",
    "a.upper()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后需要介绍一个非常有用的方法，join，这个方法可以将一个全是字符串的可迭代对象，如列表，将里面的每个元素之间，插入你想要插入的元素，返回一个新的字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(help(str.join))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = ['Tom', 'Jack', \"Jarry\"]\n",
    "print('\\n'.join(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = ['Tom', 'Jack', \"Jarry\"]\n",
    "print(', '.join(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 字典(dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的dict(字典)是非常强大的数据结构，由键值对组成，一个字典中键只允许有一个。类似其他语言中的map，他的标志是{}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = {}\n",
    "print(a)\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = dict()\n",
    "print(a)\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = {'Name': 'David'}\n",
    "print(a)\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用[]访问元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a['Name'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以用[]赋值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a['Id'] = 123"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a['Name'] = 'Jack'\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以用in判断一个元素是否是该字典中的一个键"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'Id' in a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'Name' in a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'Age' in a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用.keys()和.values()获取所有的键和所有的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.values()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in a.keys():\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in a.values():\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还可以使用.items()获得所有的键值对"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in a.items():\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到.items()返回的是一个可迭代的对象，里面每个元素都是一个元组。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在python中，给多个变量同时赋值有个小技巧"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x, y = 1, 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这实际上是利用了元组的特性，上面的1,2组成了一个只有两个元素的元组，可以对两个变量分别赋值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样可以利用这个特性交换两个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(x, y)\n",
    "x, y = y, x\n",
    "print(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "而且，如果我们要用for循环遍历一个这样的列表[(1, 2), [3, 4], (5, 6), (7, 8)]，也可以使用两个变量分别表示里面的两个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = [(1, 2), [3, 4], (5, 6), (7, 8)]\n",
    "for x, y in t:\n",
    "    print('x:', x, ',', 'y:', y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所以我们可以使用这个方法对字典的items方法的返回值进行遍历，即一个变量为键，另一个变量为值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x, y in a.items():\n",
    "    print('key:%s, value:%s'%(x, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的打印用了一个小技巧，使用%s占位，在字符串结束后，加上%()，括号里面填写要替换%s的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'%s and %s'%(\"Tom\", \"Jarry\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果我们要使用for循环对一个字典遍历，会出现什么情况？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in a:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，遍历的是字典的键"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所以遍历字典其实还有一种方式，就是遍历他的键，然后用中括号[]访问值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in a:\n",
    "    print('key: %s, value: %s'%(i, a[i]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是不推荐这种方法，如果我们需要同时遍历键和值的话，推荐使用.items()，因为使用上面的这个方法的话python会计算a[i]的值，也就是它会去计算i对应的值是多少，如果数据量大的话，这个计算时间是不容忽视的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python字典背后的结构是Hash table."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用help(dict)查看文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. 集合(set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中还有一个比较常用的结构，set（集合）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = set()\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = {1,2,3}\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = {1, }\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = {1}\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，集合的初始化方法很多，当然，还可以用set()将一个可迭代的对象转换为集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化\n",
    "a = [1,2,3]\n",
    "print(set(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "讲到这里就会提到tuple(元组)的初始化，一般使用括号初始化一个元组，但如果元组中只有一个元素，此时必须写上逗号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (1, )\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = (1)\n",
    "print(b)\n",
    "print(type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，如果不加逗号，python会自动地将括号作为运算符解释，但是集合就没有这个问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的集合内不会有任何重复的元素出现，使用add方法添加元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {1,2,3}\n",
    "a.add(4)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.add(1)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，当往集合内添加一个已经存在的元素时，不会报错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.remove(1)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用remove方法删除元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以用len()函数看一个集合的元素内的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以用sum(),max(),min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "max(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "min(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还可以使用sorted()函数返回一个排序后的列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sorted(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sorted(a, reverse = True) # 从大到小排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合还有很多常用的方法，比如求交集、并集、差集、对称差集等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 交集\n",
    "a = {1, 2, 3}\n",
    "b = {1, 2, 4}\n",
    "print(a.intersection(b))\n",
    "print(a & b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 并集\n",
    "a = {1, 2, 3}\n",
    "b = {1, 2, 4}\n",
    "print(a.union(b))\n",
    "print(a | b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 差集\n",
    "a = {1, 2, 3}\n",
    "b = {1, 2, 4}\n",
    "print(a.difference(b))\n",
    "print(a - b)\n",
    "\n",
    "print(b.difference(a))\n",
    "print(b - a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对称差集\n",
    "a = {1, 2, 3}\n",
    "b = {1, 2, 4}\n",
    "print(a.symmetric_difference(b))\n",
    "print(a ^ b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还有一些常用的方法，比如clear，update等，可以通过help(set)查看文档"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test 1\n",
    "给定一个列表，请检查出a里面不重复元素的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "temp = [random.randint(0, 1000) for i in range(1000)]\n",
    "a = [random.choice(temp) for i in range(1000)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------ start code ------\n",
    "print([([0]+a)[i] - (a+[0])[i] for i in range(len(a))].count(0))\n",
    "# ------ end code ------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
